/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   Module Name          : com.yaodian100.mall.member.web.TaobaoTopAction
   Module Description   :

   Date Created      : 2010/11/24
   Original Author   : jeffma
   Team              : yaodian100
   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   MODIFICATION HISTORY
   ------------------------------------------------------------------------------
   Date Modified       Modified by       Comments
   ------------------------------------------------------------------------------
   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
package com.yaodian100.mall.member.web;

import java.net.URLDecoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.struts2.ServletActionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.Preparable;
import com.yaodian100.core.common.dao.impl.CommonCriteria;
import com.yaodian100.core.common.utils.ServerValue;
import com.yaodian100.ec.member.entity.LoginHistory;
import com.yaodian100.ec.member.entity.Member;
import com.yaodian100.ec.member.service.MemberService;
import com.yaodian100.ec.shopping.entity.CartOrderProduct;
import com.yaodian100.ec.shopping.entity.CartOrderProductDetail;
import com.yaodian100.ec.shopping.entity.CartOrders;
import com.yaodian100.ec.shopping.service.CartOrdersService;
import com.yaodian100.ec.taobao.service.TaobaoService;
import com.yaodian100.mall.member.util.UserData;

/**
 * @author jeffma
 * 
 */
public class TaobaoTopAction extends ActionSupport implements Preparable {

	private static final long serialVersionUID = -6567253003277036716L;
	/** logger */
	private final Logger logger = LoggerFactory.getLogger(TaobaoTopAction.class);

	@Autowired
	private MemberService memberService;
	@Autowired
	private CartOrdersService cartOrdersService;
	@Autowired
	private TaobaoService taobaoService;

	private String actionResult;
	private String pathparam;

	private String custom;
	private String app_key;
	private String sign_method;
	private String sign;
	private String encode = "utf-8";

	private String visitor_nick;

	/** default constructor */
	public TaobaoTopAction() {
	}

	/**
	 * @return the actionResult
	 */
	public String getActionResult() {
		return actionResult;
	}

	/**
	 * @param actionResult the actionResult to set
	 */
	public void setActionResult(String actionResult) {
		this.actionResult = actionResult;
	}

	/**
	 * @return the encode
	 */
	public String getEncode() {
		return encode;
	}

	/**
	 * @param encode the encode to set
	 */
	public void setEncode(String encode) {
		this.encode = encode;
	}

	/**
	 * @return the pathparam
	 */
	public String getPathparam() {
		return pathparam;
	}

	/**
	 * @param pathparam the pathparam to set
	 */
	public void setPathparam(String pathparam) {
		this.pathparam = pathparam;
	}

	/**
	 * @return the custom
	 */
	public String getCustom() {
		return custom;
	}

	/**
	 * @param custom the custom to set
	 */
	public void setCustom(String custom) {
		this.custom = custom;
	}

	/**
	 * @return the app_key
	 */
	public String getApp_key() {
		return app_key;
	}

	/**
	 * @param app_key the app_key to set
	 */
	public void setApp_key(String app_key) {
		this.app_key = app_key;
	}

	/**
	 * @return the sign_method
	 */
	public String getSign_method() {
		return sign_method;
	}

	/**
	 * @param sign_method the sign_method to set
	 */
	public void setSign_method(String sign_method) {
		this.sign_method = sign_method;
	}

	/**
	 * @return the sign
	 */
	public String getSign() {
		return sign;
	}

	/**
	 * @param sign the sign to set
	 */
	public void setSign(String sign) {
		this.sign = sign;
	}

	/**
	 * @return the visitor_nick
	 */
	public String getVisitor_nick() {
		return visitor_nick;
	}

	/**
	 * @param visitor_nick the visitor_nick to set
	 */
	public void setVisitor_nick(String visitor_nick) {
		this.visitor_nick = visitor_nick;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.opensymphony.xwork2.Preparable#prepare()
	 */
	@Override
	public void prepare() throws Exception {
		clearErrorsAndMessages();
	}

	public String jump() {
		String result = "loginOK";
		HttpServletRequest request = (HttpServletRequest) ActionContext.getContext().get(ServletActionContext.HTTP_REQUEST);
		HttpServletResponse response = (HttpServletResponse) ActionContext.getContext().get(
				ServletActionContext.HTTP_RESPONSE);
		String queryString = request.getQueryString();
		Map<String, String> queryMap = new HashMap();
		pathparam = "/";
		try {
			// queryString = URLDecoder.decode(queryString, "UTF-8");
			logger.debug("queryString:" + queryString);
			if (StringUtils.isNotBlank(queryString)) {
				for (String t1 : StringUtils.split(queryString, "&")) {
					String[] t2 = StringUtils.split(t1, "=");
					queryMap.put(t2[0], URLDecoder.decode(t2[1], "UTF-8"));
				}
			}

			logger.debug("queryMap:" + queryMap);
			if (queryMap.get("top_appkey") != null && queryMap.get("top_parameters") != null
					&& queryMap.get("top_session") != null && queryMap.get("top_sign") != null) {
				Map<String, String> taobaoData = taobaoService.getParameters(queryMap.get("top_appkey"), queryMap
						.get("top_parameters"), queryMap.get("top_session"), queryMap.get("top_sign"));
				if (taobaoData.get("visitor_nick") != null) {
					checkNewMember(taobaoData.get("visitor_nick") + "@top", request);
					pathparam = StringUtils.remove(taobaoData.get("redirectURL"), ServerValue.getFrontHostname()
							+ ServerValue.getFrontContextPath());
				} else {
					logger.error("visitor_nick not found");
				}
			} else {
				boolean isCorrect = taobaoService.isValid(queryString, queryMap.get("app_key"));
				if (!isCorrect) {
					logger.error("taobao top not correct:" + queryString + ",appkey:" + queryMap.get("app_key"));
					pathparam = "/";
					result = "logout";
				} else {
					String nickName = queryMap.get("taobao_user_nick");
					if (StringUtils.isBlank(nickName)) {
						nickName = queryMap.get("visitor_nick");
					}
					if (StringUtils.isNotBlank(nickName)) {
						logger.debug("taobao nick: {}", nickName);
						checkNewMember(nickName + "@top", request);
					} else {
						logger.warn("taobao no nickname, input: {}", queryString);
					}
					if ("viewhomepage".equals(custom)) {
						pathparam = "/index.do";
					} else if ("viewitem".equals(custom)) {
						pathparam = "/product/product.do?productId=" + queryMap.get("item_id");
					} else if ("viewLogistic".equals(custom)) {
						pathparam = "/help/6_deliveryway.html";
					} else if ("modifyorder".equals(custom)) {
						pathparam = "/member/myyaodian.do";
					} else if ("viewlogistichelp".equals(custom)) {
						pathparam = "/help/6_deliverytime.html";
					} else {
						pathparam = "/index.do";
						result = "logout";
					}
				}
			}
		} catch (Exception e) {
			logger.error("taobao top error:" + queryString, e);
			pathparam = "/";
			result = "logout";
			request.setAttribute("_from", "taoabo");
		}
		Cookie cookie = new Cookie("_from", "taobao");
		cookie.setMaxAge(-1); // 1hr
		cookie.setDomain("yaodian100.com");
		cookie.setVersion(0);
		cookie.setPath("/");
		response.addCookie(cookie);
		request.setAttribute("_from", "taoabo");

		return result;
	}

	private boolean checkNewMember(String loginId, HttpServletRequest request) throws Exception {
		CommonCriteria criteria = new CommonCriteria();
		criteria.addEq("applySource", "taobaomember").addEq("loginId", loginId);
		List<Member> members = memberService.getList(0, -1, criteria, null);
		Member member = null;
		logger.debug("loginId=" + loginId);
		if (members != null && members.size() > 0) {
			member = members.get(0);
		} else {
			member = taobaoService.usersGet(loginId);

			if (member == null) {
				return false;
			}
			String host = request.getHeader("X-Forwarded-For");
			if (StringUtils.isBlank(host)) {
				host = request.getRemoteAddr();
			}
			member.setClientIp(StringUtils.abbreviate(host, 100));

			String domainSrc = request.getServerName();
			member.setDomainSrc(domainSrc);

			member = memberService.save(member);
		}
		autoLogin(member, member.getLoginId());
		return true;
	}

	private void autoLogin(Member member, String showName) throws Exception {
		logger.debug("member:" + member);
		if (null != member) {
			HttpServletRequest request = (HttpServletRequest) ActionContext.getContext().get(
					ServletActionContext.HTTP_REQUEST);
			HttpServletResponse response = (HttpServletResponse) ActionContext.getContext().get(
					ServletActionContext.HTTP_RESPONSE);
			// get ip
			String host = request.getHeader("X-Forwarded-For");
			if (StringUtils.isBlank(host)) {
				host = request.getRemoteAddr();
			}
			String clientIp = StringUtils.isBlank(host) ? "" : (host.length() > 100 ? host.substring(0, 100) : host);

			UserData userData = new UserData(request, response);
			userData.clearAll();
			userData.setLoginId(member.getLoginId());
			userData.setMemberId(member.getMemberId());
			if (StringUtils.isNotBlank(showName)) {
				userData.setShowName(showName);
			}

			memberService.checkBalance(member);
			LoginHistory loginHistory = memberService.getLastLoginHistory(member.getLoginId());
			if (null != loginHistory) {
				member.setLastLoginTime(loginHistory.getLoginTime());
				memberService.update(member);
				memberService.deleteLoginHistory(member.getLoginId());
			}
			memberService.saveFrontendLoginHistory(member, clientIp);
			memberService.checkLoginBonus(member, request.getServerName(), userData.getApplySource());

			CartOrders cartOrders = cartOrdersService.getCart(member.getMemberId(), null);
			if (cartOrders == null) {
				cartOrders = cartOrdersService.createCart(member.getMemberId(), null, null, null, 0, null, null);
			}
			String tmpCartid = StringUtils.defaultString(userData.readRawValue("cartid"));

			cartOrders = processMoveTmpCartToCartOrder(tmpCartid, cartOrders.getCartId(), cartOrdersService, userData);

			// 记录购物车商品数量
			cartOrders = cartOrdersService.get(cartOrders.getCartId());
			userData.writeRawValue(UserData.NAME_YAODIAN100_CART_ITEMS, String.valueOf(cartOrders.getProductSum()));
		}
	}

	private CartOrders processMoveTmpCartToCartOrder(String tmpCartid, String memberCartId,
			CartOrdersService cartordersService, UserData userData) throws Exception {
		// 若memberCartId為空，則新增一個cartOrders
		// logger.info("memberCartId:{}", memberCartId);
		CartOrders cartOrders = null;
		if (memberCartId == null) {
			cartOrders = cartordersService.createCart(userData.getMemberId(), null, null, null, 0, null, null);
			memberCartId = cartOrders.getCartId();
			userData.writeRawValue("cartid", cartOrders.getCartId());
			// memberCartId = createNewCartOrders(memberCartId, userData);
		} else {
			cartOrders = cartordersService.getCart(memberCartId, null);
		}
		// logger.info("cartOrders:{}", cartOrders);
		if (StringUtils.isNotBlank(tmpCartid)) {
			CartOrders tmpCart = cartordersService.get(tmpCartid);
			if (null != tmpCart) {

				// 將暫存的車移至cartOrderProduct
				for (CartOrderProduct cop : tmpCart.getCartOrderProducts()) {

					boolean isItemExists = false;
					for (CartOrderProduct memberCop : cartOrders.getCartOrderProducts()) {
						if (cop.getProdId().equals(memberCop.getProdId()) && cop.getProdSpecId().equals(memberCop.getProdSpecId())) {
							isItemExists = true;
							break;
						}
					}
					if (!isItemExists) {
						CartOrderProduct tmpcop = new CartOrderProduct();
						// tmpcop.setAmount(new BigDecimal(0.00));
						BeanUtils.copyProperties(cop, tmpcop, new String[] { "cartOrderProdId", "cartOrder", "coupon",
								"modifyDate", "details" });
						// logger.info("tmpcop:{}", tmpcop.getAmount());
						cartOrders.addCartOrderProduct(tmpcop);
						for (CartOrderProductDetail detail : cop.getDetails()) {
							CartOrderProductDetail cloneDetail = new CartOrderProductDetail();
							BeanUtils.copyProperties(detail, cloneDetail, new String[] { "cartOrderDetailId", "cartOrderProdId",
									"orderProduct", "cartId", "cartOrder", "modifyDate", "details" });
							tmpcop.addDetail(cloneDetail);

						}
					}
				}
				// 刪除暫存車的cartOrders
				cartOrders = cartordersService.save(cartOrders);
				cartordersService.delete(tmpCart);
			}
		}
		return cartOrders;
	}
}
